﻿Imports WiremetModel.Entities.OEM
Imports WiremetModel.Entities
Imports WIREMET.DictionaryExtensions

Public Class ZlecenieBiuroView

    Private _zlecenieOemDictionary As Dictionary(Of Integer, Zlecenie)
    Private _unitOfWork As UnitOfWork
    Private _detailsPanelWidth As Integer

    Private Structure Filter
        Public numerZlecenia As String
        Public klientId As Integer
        Public isDateFilterEnabled As Boolean
        Public dateStart As Date
        Public dateEnd As Date
        Public statusZleceniaId As Integer
        Public gatunekId As Integer
        Public wymiar As String
        Public pracownikId As Integer
    End Structure


    Public Sub New()

        InitializeComponent()
        SetCredentials()
        _unitOfWork = New UnitOfWork()
        RefreshViewData()
        SetInitialFilter()
        RunFilter(CreateFilter())

        _detailsPanelWidth = sc_ZlecenieView.Panel2.Width
        ChangeDetailsPanelVisibility()

    End Sub


    Private Sub ZlecenieBiuroView_FormClosed(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosedEventArgs) Handles Me.FormClosed
        _unitOfWork.Dispose()
    End Sub


    Private Sub SetCredentials()

        Dim uprawnieniaBiuro As Uprawienie = User.Role("biuro")

        If Not uprawnieniaBiuro.WyznModyfikacji AndAlso uprawnieniaBiuro.WyznOdczytu Then
            ts_btn_New.Enabled = False
            ts_btn_Edit.Enabled = False
            ts_btn_Copy.Enabled = False
        ElseIf Not uprawnieniaBiuro.WyznOdczytu Then
            ts_btn_Copy.Enabled = False
        End If

        Dim uprawnieniaWysylka As Uprawienie = User.Role("wysylka")

        If Not uprawnieniaWysylka.WyznModyfikacji AndAlso Not uprawnieniaWysylka.WyznOdczytu Then
            ts_btn_Shipment.Enabled = False
        End If
    End Sub


    Private Sub RefreshViewData()

        Dim zleceniaOemRepository As New Repository(Of Zlecenie)(_unitOfWork)
        Dim statusRepository As New Repository(Of Status)(_unitOfWork)
        Dim klientRepository As New Repository(Of Klient)(_unitOfWork)
        Dim gatunekRepository As New Repository(Of Gatunek)(_unitOfWork)
        Dim pracownikRepository As New Repository(Of Pracownik)(_unitOfWork)

        _zlecenieOemDictionary = zleceniaOemRepository.GetAll().ToDictionary(Function(x) x.Id, Function(x) x)
        Dim klientList As IEnumerable(Of Klient) = klientRepository.GetAll().OrderBy(Function(x) x.NazwaSkrocona)
        Dim statusZleceniaList As IEnumerable(Of Status) = statusRepository.GetAll().OrderBy(Function(x) x.Nazwa)
        Dim gatunekList As IEnumerable(Of Gatunek) = gatunekRepository.GetAll().OrderBy(Function(x) x.NazwaAng)
        Dim pracownikList As IEnumerable(Of Pracownik) = pracownikRepository.GetAll().OrderBy(Function(x) x.ToString())

        InitializeFilterComboBox(cmb_NazwaFirmy, klientList.ToDictionary(Function(x) x.Id, Function(x) x.NazwaSkrocona))
        InitializeFilterComboBox(cmb_StatusZlecenia, statusZleceniaList.ToDictionary(Function(x) x.Id, Function(x) x.Nazwa))
        InitializeFilterComboBox(cmb_Gatunek, gatunekList.ToDictionary(Function(x) x.Id, Function(x) x.NazwaAng))
        InitializeFilterComboBox(cmb_Pracownik, pracownikList.ToDictionary(Function(x) x.Id, Function(x) x.ToString()))

    End Sub


    Private Sub InitializeFilterComboBox(ByRef cmbFilter As ComboBox, ByVal data As Dictionary(Of Integer, String))

        cmbFilter.DataSource = New BindingSource(data, Nothing)
        cmbFilter.DisplayMember = "Value"
        cmbFilter.ValueMember = "Key"
        cmbFilter.AutoCompleteCustomSource.Clear()
        cmbFilter.AutoCompleteCustomSource.AddRange(data.Values.OrderBy(Function(x) x).ToArray())
        cmbFilter.SelectedIndex = -1

    End Sub


    Private Sub SetInitialFilter()
        'cmb_StatusZlecenia.SelectedValue = 4
    End Sub


    Private Sub SetInitialFilter(filter As Filter)
        tb_NumerZlecenia.Text = filter.numerZlecenia
        cmb_NazwaFirmy.SelectedValue = filter.klientId
        cmb_StatusZlecenia.SelectedValue = filter.statusZleceniaId
        cmb_Gatunek.SelectedValue = filter.gatunekId
        tb_FiltrWymiar.Text = filter.wymiar
    End Sub

    Private Sub RefreshZleceniaTable(ByVal zleceniaList As IEnumerable(Of Zlecenie))

        dgv_Zlecenia.Rows.Clear()

        For Each zlecenie As Zlecenie In zleceniaList

            Dim index As Integer = dgv_Zlecenia.Rows.Add(
                zlecenie.Id,
                zlecenie.Numer,
                zlecenie.Klient.NazwaSkrocona,
                zlecenie.DataZamowienia.ToShortDateString(),
                zlecenie.Termin.ToShortDateString(),
                zlecenie.Status.Nazwa)

            If zlecenie.Termin < Date.Now.Date Then
                dgv_Zlecenia.Rows(index).DefaultCellStyle.BackColor = My.Settings.Red350
            ElseIf zlecenie.Termin >= Date.Now.Date AndAlso zlecenie.Termin <= Date.Now.Date.AddDays(1) Then
                dgv_Zlecenia.Rows(index).DefaultCellStyle.BackColor = My.Settings.Yellow500
            End If
        Next
    End Sub


    Private Function CreateFilter() As Filter
        Return New Filter With
        {
            .numerZlecenia = tb_NumerZlecenia.Text.Trim(),
            .klientId = CInt(cmb_NazwaFirmy.SelectedValue),
            .isDateFilterEnabled = cb_DataRealizacji.Checked,
            .dateStart = dtp_DataRealizacjiPoczatkowa.Value.Date,
            .dateEnd = dtp_DataRealizacjiKoncowa.Value.Date,
            .statusZleceniaId = CInt(cmb_StatusZlecenia.SelectedValue),
            .gatunekId = CInt(cmb_Gatunek.SelectedValue),
            .wymiar = tb_FiltrWymiar.Text.Trim(),
            .pracownikId = CInt(cmb_Pracownik.SelectedValue)
        }
    End Function


    Private Function IsZlecenieSatisfiedByFilter(ByVal zlecenie As Zlecenie, ByVal filter As Filter) As Boolean

        Return zlecenie.Numer.StartsWith(filter.numerZlecenia, StringComparison.CurrentCultureIgnoreCase) AndAlso
                               (filter.klientId = 0 OrElse zlecenie.Klient.Id = filter.klientId) AndAlso
                               (Not filter.isDateFilterEnabled OrElse (zlecenie.Termin >= filter.dateStart AndAlso zlecenie.Termin <= filter.dateEnd)) AndAlso
                               (filter.statusZleceniaId = 0 OrElse zlecenie.Status.Id = filter.statusZleceniaId) AndAlso
                               (filter.gatunekId = 0 OrElse zlecenie.PozycjeZlecenia.Any(Function(x) x.Gatunek.Id = filter.gatunekId)) AndAlso
                               (String.IsNullOrEmpty(filter.wymiar) OrElse zlecenie.PozycjeZlecenia.Where(Function(x) x.Wymiar.StartsWith(filter.wymiar, StringComparison.CurrentCultureIgnoreCase)).Count > 0) AndAlso
                               (filter.pracownikId = 0 OrElse zlecenie.Pracownik.Id = filter.pracownikId)
    End Function


    Private Sub RunFilter(ByVal filter As Filter)

        Dim filteredZlecenia As New List(Of Zlecenie)

        For Each zlecenie As Zlecenie In _zlecenieOemDictionary.Values
            If CBool(IsZlecenieSatisfiedByFilter(zlecenie, filter)) Then
                filteredZlecenia.Add(zlecenie)
            End If
        Next

        dgv_Zlecenia.Rows.Clear()
        RefreshZleceniaTable(filteredZlecenia.OrderByDescending(Function(x) x.Termin))

        ComboBoxCleanupWhenNoValueSelected(cmb_Gatunek)
        ComboBoxCleanupWhenNoValueSelected(cmb_NazwaFirmy)
        ComboBoxCleanupWhenNoValueSelected(cmb_StatusZlecenia)
        ComboBoxCleanupWhenNoValueSelected(cmb_Pracownik)

    End Sub


    Private Sub ComboBoxCleanupWhenNoValueSelected(ByRef comboBox As ComboBox)
        If comboBox.SelectedValue Is Nothing Then
            comboBox.ResetText()
        End If
    End Sub


    Private Sub ClearFilter()

        tb_NumerZlecenia.Text = String.Empty
        cmb_NazwaFirmy.ResetText()
        cmb_NazwaFirmy.SelectedIndex = -1
        cb_DataRealizacji.Checked = False
        cmb_StatusZlecenia.ResetText()
        cmb_StatusZlecenia.SelectedIndex = -1
        cmb_Gatunek.ResetText()
        cmb_Gatunek.SelectedIndex = -1
        tb_FiltrWymiar.Text = String.Empty
        cmb_Pracownik.ResetText()
        cmb_Pracownik.SelectedIndex = -1

    End Sub


    Private Sub btn_RunFilter_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btn_RunFilter.Click
        RunFilter(CreateFilter())
    End Sub

    Private Sub RefreshView()
        Cursor = Cursors.WaitCursor
        Dim filter As Filter = CreateFilter()
        _unitOfWork.Dispose()
        _unitOfWork = New UnitOfWork()
        RefreshViewData()
        'ClearFilter()
        SetInitialFilter(filter)
        RunFilter(filter)
        Cursor = Cursors.Default
    End Sub

    Private Sub ts_btn_RefreshView_Click(sender As System.Object, e As System.EventArgs) Handles ts_btn_RefreshView.Click
        RefreshView()
    End Sub


    Private Sub btn_ClearFilter_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btn_ClearFilter.Click
        ClearFilter()
        RunFilter(CreateFilter())
    End Sub


    Private Sub filterInput_KeyDown(ByVal sender As Object, ByVal e As KeyEventArgs) Handles tb_NumerZlecenia.KeyDown, cmb_NazwaFirmy.KeyDown, cmb_StatusZlecenia.KeyDown, cmb_Gatunek.KeyDown, tb_FiltrWymiar.KeyDown, cmb_Pracownik.KeyDown
        If e.KeyCode = Keys.Enter Then
            RunFilter(CreateFilter())
        End If
    End Sub


    Private Sub dtpDataRealizacji_TextChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles dtp_DataRealizacjiPoczatkowa.ValueChanged, dtp_DataRealizacjiKoncowa.ValueChanged
        cb_DataRealizacji.Checked = True
    End Sub



    Private Sub RefreshDetailsPozycjeZleceniaTable(ByVal pozycjaZleceniaList As IEnumerable(Of PozycjaZlecenia))
        dgv_PozycjeZlecenia.Rows.Clear()
        For Each pozycjaZlecenia As PozycjaZlecenia In pozycjaZleceniaList
            dgv_PozycjeZlecenia.Rows.Add(
                pozycjaZlecenia.Id,
                pozycjaZlecenia.NumerPozycji,
                pozycjaZlecenia.Wymiar,
                pozycjaZlecenia.Gatunek.NazwaAng,
                pozycjaZlecenia.Ilosc,
                pozycjaZlecenia.Cena)
        Next
    End Sub


    Private Sub RefreshDetails(ByVal zlecenie As Zlecenie)

        tb_DataUtworzenia.Text = CStr(zlecenie.DataUtworzenia)
        tb_Pracownik.Text = zlecenie.Pracownik.Nazwisko & " " & zlecenie.Pracownik.Imie
        tb_SposobZamowienia.Text = zlecenie.SposobZamowienia.Nazwa
        tb_StatusWysylki.Text = zlecenie.StatusWysylki.Nazwa
        tb_Uwagi.Text = zlecenie.Uwagi
        RefreshDetailsPozycjeZleceniaTable(zlecenie.PozycjeZlecenia.OrderBy(Function(x) x.NumerPozycji))

    End Sub





    Private Sub RefreshDetails()
        If Not sc_ZlecenieView.Panel2Collapsed AndAlso Not dgv_Zlecenia.SelectedRows.Count = 0 Then
            Dim zlecenieId As Integer = CInt(dgv_Zlecenia.SelectedRows(0).Cells("ZlecenieId").Value)
            RefreshDetails(_zlecenieOemDictionary(zlecenieId))
        End If
    End Sub


    Private Sub dgv_Zlecenia_SelectionChanged(ByVal sender As System.Object, ByVal e As EventArgs) Handles dgv_Zlecenia.SelectionChanged
        RefreshDetails()
    End Sub


    Private Function GetSelectedZlecenie() As Zlecenie
        Return _zlecenieOemDictionary(CInt(dgv_Zlecenia.SelectedRows(0).Cells("ZlecenieId").Value))
    End Function


    Private Sub EnsureZlecenieIsSelected()
        If dgv_Zlecenia.SelectedRows.Count = 0 Then
            Throw New Exception("Proszę, wybierz zlecenie, aby kontynuować.")
        End If
    End Sub


    Private Sub dgv_Zlecenia_CellMouseDoubleClick(ByVal sender As Object, ByVal e As DataGridViewCellMouseEventArgs) Handles dgv_Zlecenia.CellMouseDoubleClick
        Try
            Dim uprawnieniaBiuro As Uprawienie = User.Role.GetValueOrDefault("biuro")
            If uprawnieniaBiuro.WyznModyfikacji OrElse uprawnieniaBiuro.WyznOdczytu Then
                EnsureZlecenieIsSelected()
                Dim zlecenieId As Integer = GetSelectedZlecenie().Id
                Dim zlecenieForm As New frmZlecenia(zlecenieId, 0)
                zlecenieForm.MdiParent = MdiParent
                zlecenieForm.Show()
            End If

        Catch ex As Exception
            MessageBox.Show(ex.Message, "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning)
        End Try
    End Sub

    Private Sub ts_btn_New_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ts_btn_New.Click
        Dim zlecenieForm As New frmZlecenia(0, 0)
        zlecenieForm.MdiParent = MdiParent
        zlecenieForm.Show()
    End Sub

    Private Sub ts_btn_Edit_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ts_btn_Edit.Click
        Try
            EnsureZlecenieIsSelected()
            Dim zlecenieId As Integer = GetSelectedZlecenie().Id

            Dim zlecenieForm As New frmZlecenia(zlecenieId, 0)
            zlecenieForm.MdiParent = MdiParent
            zlecenieForm.Show()

        Catch ex As Exception
            MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
        End Try
    End Sub

    Private Sub ts_btn_Copy_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ts_btn_Copy.Click
        Try
            EnsureZlecenieIsSelected()
            Dim zlecenieId As Integer = GetSelectedZlecenie().Id

            Dim zlecenieForm As New frmZlecenia(zlecenieId, 1)
            zlecenieForm.MdiParent = MdiParent
            zlecenieForm.Show()

        Catch ex As Exception
            MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
        End Try
    End Sub

    Private Sub ts_btn_Shipment_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ts_btn_Shipment.Click
        Try
            EnsureZlecenieIsSelected()
            Dim zlecenieId As Integer = GetSelectedZlecenie().Id
            Dim zlecenieTrackingId As Integer = clsInhTrZlecenie.PobierzIdZleceniaTr(New clsDataBase(VAR_CONNECTION_PARAMETERS, VAR_ERROR_HANDLER), zlecenieId)

            Dim wysylkaForm As New frmWysylka2(zlecenieTrackingId, 0)
            wysylkaForm.MdiParent = MdiParent
            wysylkaForm.Show()

        Catch ex As Exception
            MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
        End Try
    End Sub

    Private Sub ChangeDetailsPanelVisibility()
        If sc_ZlecenieView.Panel2Collapsed Then
            sc_ZlecenieView.Panel2Collapsed = False
            Me.Width += _detailsPanelWidth + sc_ZlecenieView.SplitterWidth
        Else
            _detailsPanelWidth = sc_ZlecenieView.Panel2.Width
            Me.Width -= _detailsPanelWidth + sc_ZlecenieView.SplitterWidth
            sc_ZlecenieView.Panel2Collapsed = True
        End If
        Refresh()
    End Sub

    Private Sub ts_btn_Details_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ts_btn_Details.Click
        ChangeDetailsPanelVisibility()
        RefreshDetails()
    End Sub

    Private Sub ts_btn_OrderWastes_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)
        Try
            EnsureZlecenieIsSelected()
            Dim zlecenieTracking As Tracking.Zlecenie = GetSelectedZlecenie().ZlecenieTracking.FirstOrDefault()
            If zlecenieTracking Is Nothing Then
                Throw New Exception("Wybrana pozycja zlecenia nie została przesłana na produkcję.")
            End If
            Dim odpadyZleceniaForm As New OdpadyZleceniaView(zlecenieTracking.Id)
            odpadyZleceniaForm.MdiParent = MdiParent
            odpadyZleceniaForm.Show()
        Catch ex As Exception
            MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
        End Try
    End Sub

    
    Private Sub ts_btn_MonthSummary_Click(sender As System.Object, e As System.EventArgs) Handles ts_btn_MonthSummary.Click
        Try
            Dim yearMonthInputDialog As New YearMonthInputDialog()
            If yearMonthInputDialog.ShowDialog() <> Windows.Forms.DialogResult.OK Then
                Return
            End If


            Dim year As Integer = yearMonthInputDialog.Year
            Dim month As Integer = yearMonthInputDialog.Month

            Dim zlecenieRepository As New Repository(Of Zlecenie)(_unitOfWork)
            Dim zleceniaList As IList(Of Zlecenie) = zlecenieRepository.GetAll().ToList()
            Dim zleceniaMiesiaca As IList(Of Zlecenie) = zleceniaList.Where(Function(x) x.DataZamowienia.Year = year AndAlso x.DataZamowienia.Month = month).ToList()
            Dim zleceniaKrajowe As IList(Of Zlecenie) = zleceniaMiesiaca.Where(Function(x) x.Klient.Kraj.Equals("polska", StringComparison.InvariantCultureIgnoreCase)).ToList()
            Dim zleceniaZagraniczne As IList(Of Zlecenie) = zleceniaMiesiaca.Where(Function(x) Not x.Klient.Kraj.Equals("polska", StringComparison.InvariantCultureIgnoreCase)).ToList()

            Dim pozycjeZlecenKrajowe As IList(Of PozycjaZlecenia) = zleceniaKrajowe.SelectMany(Function(x) x.PozycjeZlecenia).ToList()
            Dim pozycjeZlecenZagraniczne As IList(Of PozycjaZlecenia) = zleceniaZagraniczne.SelectMany(Function(x) x.PozycjeZlecenia).ToList()

            Dim pozycjeZlecenZagranicznePLN As IList(Of PozycjaZlecenia) = pozycjeZlecenZagraniczne.Where(Function(x) x.Waluta.Id = 1).ToList()
            Dim pozycjeZlecenZagraniczneEURO As IList(Of PozycjaZlecenia) = pozycjeZlecenZagraniczne.Where(Function(x) x.Waluta.Id = 2).ToList()


            Dim cenaKrajowych As Double = pozycjeZlecenKrajowe.Sum(Function(x) x.Cena * Double.Parse(x.Ilosc) + If(x.CenaOpakowania, x.Pakowanie.Cena, 0))
            Dim cenaZagranicznychPLN As Double = pozycjeZlecenZagranicznePLN.Sum(Function(x) x.Cena * Double.Parse(x.Ilosc) + If(x.CenaOpakowania, x.Pakowanie.Cena, 0))
            Dim cenaZagranicznychEuro As Double = pozycjeZlecenZagraniczneEURO.Sum(Function(x) x.Cena * Double.Parse(x.Ilosc) + If(x.CenaOpakowania, x.Pakowanie.Cena, 0))

            MessageBox.Show("suma cen krajowych zleceń: " + cenaKrajowych.ToString() + " zł" + vbNewLine +
                            "suma cen zagranicznych zleceń: " + cenaZagranicznychPLN.ToString() + " zł" + " i " + cenaZagranicznychEuro.ToString() + " euro")

        Catch ex As Exception
            MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
        End Try
    End Sub
End Class